package com.star.tool.util;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.AnimRes;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v4.util.Pair;
import android.view.View;

import com.star.tool.Utils;

import java.util.List;

/**
 * Author: blackbai11
 * Date: 2016/2/18 10:11
 * Description:  Activity工具类
 */
public final class ActivityUtils {

    private ActivityUtils() {
        throw new UnsupportedOperationException("u can't instantiate me...");
    }

    /**
     * 判断 Activity 是否存在
     * @param pkg context.getPackageName()
     * @param cls activity.class.getName()
     * 原理:resolveActivity是否有activity能够处理Intent请求
     */
    public static boolean isActivityExists(@NonNull final String pkg,
                                           @NonNull final String cls) {
        Intent intent = new Intent();
        intent.setClassName(pkg, cls);
        return !(Utils.getApp().getPackageManager().resolveActivity(intent, 0) == null ||
                intent.resolveActivity(Utils.getApp().getPackageManager()) == null ||
                Utils.getApp().getPackageManager().queryIntentActivities(intent, 0).size() == 0);
    }

    /**
     * 启动 Activity(基础跳转)
     * @param clz activity.class
     */
    public static void startActivity(@NonNull final Class<? extends Activity> clz) {
        Context context = Utils.getTopActivityOrApp();
        startActivity(context, null, context.getPackageName(), clz.getName(), null);
    }

    /**
     * 启动 Activity + 动画
     * @param clz     activity.class
     * @param options activity跳转方式（ActivityOptionsCompat.xxx.toBundle动画设置）
     * 原理:ActivityOptionsCompat.xxx.toBundle
     */
    public static void startActivity(@NonNull final Class<? extends Activity> clz,
                                     final Bundle options) {
        Context context = Utils.getTopActivityOrApp();
        startActivity(context, null, context.getPackageName(), clz.getName(), options);
    }

    /**
     * 启动 Activity + 动画
     * @param clz       activity.class
     * @param enterAnim 进入动画资源
     * @param exitAnim  退出动画资源
     * 原理:ActivityOptionsCompat.makeCustomAnimation
     */
    public static void startActivity(@NonNull final Class<? extends Activity> clz,
                                     @AnimRes final int enterAnim,
                                     @AnimRes final int exitAnim) {
        Context context = Utils.getTopActivityOrApp();
        startActivity(context, null, context.getPackageName(), clz.getName(),
                getOptionsBundle(context, enterAnim, exitAnim));
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN && context instanceof Activity) { //api16-4.1 以下
            ((Activity) context).overridePendingTransition(enterAnim, exitAnim);
        }
    }

    /**
     * 启动 Activity
     * @param activity activity
     * @param clz      activity.class
     */
    public static void startActivity(@NonNull final Activity activity,
                                     @NonNull final Class<? extends Activity> clz) {
        startActivity(activity, null, activity.getPackageName(), clz.getName(), null);
    }

    /**
     * 启动 Activity + 动画
     * @param activity activity
     * @param clz      activity.class
     * @param options  activity跳转方式（ActivityOptionsCompat.xxx.toBundle动画设置）
     */
    public static void startActivity(@NonNull final Activity activity,
                                     @NonNull final Class<? extends Activity> clz,
                                     final Bundle options) {
        startActivity(activity, null, activity.getPackageName(), clz.getName(), options);
    }

    /**
     * 启动 Activity + 场景动画
     * @param activity       activity
     * @param clz            activity.class
     * @param sharedElements 需要执行协调动画的view（可变参数）
     */
    public static void startActivity(@NonNull final Activity activity,
                                     @NonNull final Class<? extends Activity> clz,
                                     final View... sharedElements) {
        startActivity(activity, null, activity.getPackageName(), clz.getName(),
                getOptionsBundle(activity, sharedElements));
    }

    /**
     * 启动 Activity + 动画
     * @param activity  activity
     * @param clz       activity.class
     * @param enterAnim 进入动画资源
     * @param exitAnim  退出动画资源
     * 原理:ActivityOptionsCompat.makeCustomAnimation
     */
    public static void startActivity(@NonNull final Activity activity,
                                     @NonNull final Class<? extends Activity> clz,
                                     @AnimRes final int enterAnim,
                                     @AnimRes final int exitAnim) {
        startActivity(activity, null, activity.getPackageName(), clz.getName(),
                getOptionsBundle(activity, enterAnim, exitAnim));
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {    //api16-4.1 以下
            activity.overridePendingTransition(enterAnim, exitAnim);
        }
    }

    /**
     * 启动 Activity
     * @param extras bundle 数据
     * @param clz    activity.class
     */
    public static void startActivity(@NonNull final Bundle extras,
                                     @NonNull final Class<? extends Activity> clz) {
        Context context = Utils.getTopActivityOrApp();
        startActivity(context, extras, context.getPackageName(), clz.getName(), null);
}

    /**
     * 启动 Activity + 动画
     * @param extras  bundle 数据
     * @param clz     activity.class
     * @param options activity跳转方式
     */
    public static void startActivity(@NonNull final Bundle extras,
                                     @NonNull final Class<? extends Activity> clz,
                                     @NonNull final Bundle options) {
        Context context = Utils.getTopActivityOrApp();
        startActivity(context, extras, context.getPackageName(), clz.getName(), options);
    }

    /**
     * 启动 Activity + 动画
     * @param extras    bundle 数据
     * @param clz       activity.class
     * @param enterAnim 进入动画资源
     * @param exitAnim  退出动画资源
     */
    public static void startActivity(@NonNull final Bundle extras,
                                     @NonNull final Class<? extends Activity> clz,
                                     @AnimRes final int enterAnim,
                                     @AnimRes final int exitAnim) {
        Context context = Utils.getTopActivityOrApp();
        startActivity(context, extras, context.getPackageName(), clz.getName(),
                getOptionsBundle(context, enterAnim, exitAnim));
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN && context instanceof Activity) {
            ((Activity) context).overridePendingTransition(enterAnim, exitAnim);
        }
    }

    /**
     * 启动 Activity
     * @param extras   bundle 数据
     * @param activity activity
     * @param clz      activity.class
     */
    public static void startActivity(@NonNull final Bundle extras,
                                     @NonNull final Activity activity,
                                     @NonNull final Class<? extends Activity> clz) {
        startActivity(activity, extras, activity.getPackageName(), clz.getName(), null);
    }

    /**
     * 启动 Activity + 动画
     * @param extras   bundle 数据
     * @param activity activity
     * @param clz      activity.class
     * @param options  activity跳转方式
     */
    public static void startActivity(@NonNull final Bundle extras,
                                     @NonNull final Activity activity,
                                     @NonNull final Class<? extends Activity> clz,
                                     @NonNull final Bundle options) {
        startActivity(activity, extras, activity.getPackageName(), clz.getName(), options);
    }

    /**
     * 启动 Activity + 动画
     * @param extras         bundle 数据
     * @param activity       activity
     * @param clz            activity.class
     * @param sharedElements 需要执行协调动画的view（可变参数）
     */
    public static void startActivity(@NonNull final Bundle extras,
                                     @NonNull final Activity activity,
                                     @NonNull final Class<? extends Activity> clz,
                                     final View... sharedElements) {
        startActivity(activity, extras, activity.getPackageName(), clz.getName(),
                getOptionsBundle(activity, sharedElements));
    }

    /**
     * 启动 Activity + 动画
     * @param extras    bundle 数据
     * @param activity  activity
     * @param clz       activity.class
     * @param enterAnim 进入动画资源
     * @param exitAnim  退出动画资源
     */
    public static void startActivity(@NonNull final Bundle extras,
                                     @NonNull final Activity activity,
                                     @NonNull final Class<? extends Activity> clz,
                                     @AnimRes final int enterAnim,
                                     @AnimRes final int exitAnim) {
        startActivity(activity, extras, activity.getPackageName(), clz.getName(),
                getOptionsBundle(activity, enterAnim, exitAnim));
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            activity.overridePendingTransition(enterAnim, exitAnim);
        }
    }

    /**
     * 启动 Activity
     * @param pkg context.getPackageName()
     * @param cls activity.class
     */
    public static void startActivity(@NonNull final String pkg,
                                     @NonNull final String cls) {
        startActivity(Utils.getTopActivityOrApp(), null, pkg, cls, null);
    }

    /**
     * 启动 Activity + 动画
     * @param pkg context.getPackageName()
     * @param cls activity.class
     * @param options  activity跳转方式
     */
    public static void startActivity(@NonNull final String pkg,
                                     @NonNull final String cls,
                                     final Bundle options) {
        startActivity(Utils.getTopActivityOrApp(), null, pkg, cls, options);
    }

    /**
     * 启动 Activity + 动画
     * @param pkg       context.getPackageName()
     * @param cls       activity.class
     * @param enterAnim 进入动画资源
     * @param exitAnim  退出动画资源
     */
    public static void startActivity(@NonNull final String pkg,
                                     @NonNull final String cls,
                                     @AnimRes final int enterAnim,
                                     @AnimRes final int exitAnim) {
        Context context = Utils.getTopActivityOrApp();
        startActivity(context, null, pkg, cls, getOptionsBundle(context, enterAnim, exitAnim));
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN && context instanceof Activity) {
            ((Activity) context).overridePendingTransition(enterAnim, exitAnim);
        }
    }

    /**
     * 启动 Activity
     * @param activity  activity
     * @param pkg       context.getPackageName()
     * @param cls       activity.class
     */
    public static void startActivity(@NonNull final Activity activity,
                                     @NonNull final String pkg,
                                     @NonNull final String cls) {
        startActivity(activity, null, pkg, cls, null);
    }

    /**
     * 启动 Activity + 动画
     * @param activity  activity
     * @param pkg       context.getPackageName()
     * @param cls       activity.class
     * @param options   activity跳转方式
     */
    public static void startActivity(@NonNull final Activity activity,
                                     @NonNull final String pkg,
                                     @NonNull final String cls,
                                     final Bundle options) {
        startActivity(activity, null, pkg, cls, options);
    }

    /**
     * 启动 Activity + 动画
     * @param activity       activity
     * @param pkg            context.getPackageName()
     * @param cls            activity.class
     * @param sharedElements 需要执行协调动画的view（可变参数）
     */
    public static void startActivity(@NonNull final Activity activity,
                                     @NonNull final String pkg,
                                     @NonNull final String cls,
                                     final View... sharedElements) {
        startActivity(activity, null, pkg, cls, getOptionsBundle(activity, sharedElements));
    }

    /**
     * 启动 Activity + 动画
     * @param activity       activity
     * @param pkg            context.getPackageName()
     * @param cls            activity.class
     * @param enterAnim      进入动画资源
     * @param exitAnim       退出动画资源
     */
    public static void startActivity(@NonNull final Activity activity,
                                     @NonNull final String pkg,
                                     @NonNull final String cls,
                                     @AnimRes final int enterAnim,
                                     @AnimRes final int exitAnim) {
        startActivity(activity, null, pkg, cls, getOptionsBundle(activity, enterAnim, exitAnim));
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            activity.overridePendingTransition(enterAnim, exitAnim);
        }
    }

    /**
     * 启动 Activity
     * @param extras bundle 数据
     * @param pkg    context.getPackageName()
     * @param cls    activity.class
     */
    public static void startActivity(@NonNull final Bundle extras,
                                     @NonNull final String pkg,
                                     @NonNull final String cls) {
        startActivity(Utils.getTopActivityOrApp(), extras, pkg, cls, null);
    }

    /**
     * 启动 Activity + 动画
     * @param extras  bundle 数据
     * @param pkg     context.getPackageName()
     * @param cls     activity.class
     * @param options activity跳转方式
     */
    public static void startActivity(@NonNull final Bundle extras,
                                     @NonNull final String pkg,
                                     @NonNull final String cls,
                                     final Bundle options) {
        startActivity(Utils.getTopActivityOrApp(), extras, pkg, cls, options);
    }

    /**
     * 启动 Activity + 动画
     * @param extras  bundle 数据
     * @param pkg     context.getPackageName()
     * @param cls     activity.class
     * @param enterAnim      进入动画资源
     * @param exitAnim       退出动画资源
     */
    public static void startActivity(@NonNull final Bundle extras,
                                     @NonNull final String pkg,
                                     @NonNull final String cls,
                                     @AnimRes final int enterAnim,
                                     @AnimRes final int exitAnim) {
        Context context = Utils.getTopActivityOrApp();
        startActivity(context, extras, pkg, cls, getOptionsBundle(context, enterAnim, exitAnim));
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN && context instanceof Activity) {
            ((Activity) context).overridePendingTransition(enterAnim, exitAnim);
        }
    }

    /**
     * 启动 Activity
     * @param extras   bundle 数据
     * @param activity activity
     * @param pkg      context.getPackageName()
     * @param cls      activity.class
     */
    public static void startActivity(@NonNull final Bundle extras,
                                     @NonNull final Activity activity,
                                     @NonNull final String pkg,
                                     @NonNull final String cls) {
        startActivity(activity, extras, pkg, cls, null);
    }

    /**
     * 启动 Activity  + 动画
     * @param extras   bundle 数据
     * @param activity activity
     * @param pkg      context.getPackageName()
     * @param cls      activity.class
     * @param options  activity跳转方式
     */
    public static void startActivity(@NonNull final Bundle extras,
                                     @NonNull final Activity activity,
                                     @NonNull final String pkg,
                                     @NonNull final String cls,
                                     final Bundle options) {
        startActivity(activity, extras, pkg, cls, options);
    }

    /**
     * 启动 Activity  + 动画
     * @param extras         bundle 数据
     * @param activity       activity
     * @param pkg            context.getPackageName()
     * @param cls            activity.class
     * @param sharedElements 需要执行协调动画的view（可变参数）
     */
    public static void startActivity(@NonNull final Bundle extras,
                                     @NonNull final Activity activity,
                                     @NonNull final String pkg,
                                     @NonNull final String cls,
                                     final View... sharedElements) {
        startActivity(activity, extras, pkg, cls, getOptionsBundle(activity, sharedElements));
    }

    /**
     * 启动 Activity  + 动画
     * @param extras         bundle 数据
     * @param activity       activity
     * @param pkg            context.getPackageName()
     * @param cls            activity.class
     * @param enterAnim      进入动画资源
     * @param exitAnim       退出动画资源
     */
    public static void startActivity(@NonNull final Bundle extras,
                                     @NonNull final Activity activity,
                                     @NonNull final String pkg,
                                     @NonNull final String cls,
                                     @AnimRes final int enterAnim,
                                     @AnimRes final int exitAnim) {
        startActivity(activity, extras, pkg, cls, getOptionsBundle(activity, enterAnim, exitAnim));
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            activity.overridePendingTransition(enterAnim, exitAnim);
        }
    }

    /**
     * 启动 Activity
     * @param intent intent
     */
    public static void startActivity(@NonNull final Intent intent) {
        startActivity(intent, Utils.getTopActivityOrApp(), null);
    }

    /**
     * 启动 Activity + 动画
     * @param intent  intent
     * @param options activity跳转方式
     */
    public static void startActivity(@NonNull final Intent intent,
                                     @NonNull final Bundle options) {
        startActivity(intent, Utils.getTopActivityOrApp(), options);
    }

    /**
     * 启动 Activity + 动画
     * @param intent    intent
     * @param enterAnim 进入动画资源
     * @param exitAnim  退出动画资源
     */
    public static void startActivity(@NonNull final Intent intent,
                                     @AnimRes final int enterAnim,
                                     @AnimRes final int exitAnim) {
        Context context = Utils.getTopActivityOrApp();
        startActivity(intent, context, getOptionsBundle(context, enterAnim, exitAnim));
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN && context instanceof Activity) {
            ((Activity) context).overridePendingTransition(enterAnim, exitAnim);
        }
    }

    /**
     * 启动 Activity
     * @param activity activity
     * @param intent   intent
     */
    public static void startActivity(@NonNull final Activity activity,
                                     @NonNull final Intent intent) {
        startActivity(intent, activity, null);
    }

    /**
     * 启动 Activity + 动画
     * @param activity activity
     * @param intent   intent
     * @param options activity跳转方式
     */
    public static void startActivity(@NonNull final Activity activity,
                                     @NonNull final Intent intent,
                                     final Bundle options) {
        startActivity(intent, activity, options);
    }

    /**
     * 启动 Activity + 动画
     * @param activity       activity
     * @param intent         intent
     * @param sharedElements 需要执行协调动画的view（可变参数）
     */
    public static void startActivity(@NonNull final Activity activity,
                                     @NonNull final Intent intent,
                                     final View... sharedElements) {
        startActivity(intent, activity, getOptionsBundle(activity, sharedElements));
    }

    /**
     * 启动 Activity + 动画
     * @param activity  activity
     * @param intent    intent
     * @param enterAnim 进入动画资源
     * @param exitAnim  退出动画资源
     */
    public static void startActivity(@NonNull final Activity activity,
                                     @NonNull final Intent intent,
                                     @AnimRes final int enterAnim,
                                     @AnimRes final int exitAnim) {
        startActivity(intent, activity, getOptionsBundle(activity, enterAnim, exitAnim));
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            activity.overridePendingTransition(enterAnim, exitAnim);
        }
    }

    /**
     * 启动 Activity 并带结果返回
     * @param activity    activity
     * @param clz         activity.class
     * @param requestCode 请求码
     */
    public static void startActivityForResult(@NonNull final Activity activity,
                                              @NonNull final Class<? extends Activity> clz,
                                              final int requestCode) {
        startActivityForResult(activity, null, activity.getPackageName(), clz.getName(),
                requestCode, null);
    }

    /**
     * 启动 Activity 并带结果返回 + 动画
     * @param activity    activity
     * @param clz         activity.class
     * @param requestCode 请求码
     * @param options     activity跳转方式
     */
    public static void startActivityForResult(@NonNull final Activity activity,
                                              @NonNull final Class<? extends Activity> clz,
                                              final int requestCode,
                                              final Bundle options) {
        startActivityForResult(activity, null, activity.getPackageName(), clz.getName(),
                requestCode, options);
    }

    /**
     * 启动 Activity 并带结果返回 + 动画
     * @param activity       activity
     * @param clz            activity.class
     * @param requestCode    请求码
     * @param sharedElements 需要执行协调动画的view（可变参数）
     */
    public static void startActivityForResult(@NonNull final Activity activity,
                                              @NonNull final Class<? extends Activity> clz,
                                              final int requestCode,
                                              final View... sharedElements) {
        startActivityForResult(activity, null, activity.getPackageName(), clz.getName(),
                requestCode, getOptionsBundle(activity, sharedElements));
    }

    /**
     * 启动 Activity 并带结果返回 + 动画
     * @param activity    activity
     * @param clz         activity.class
     * @param requestCode 请求码
     * @param enterAnim   进入动画资源
     * @param exitAnim    退出动画资源
     */
    public static void startActivityForResult(@NonNull final Activity activity,
                                              @NonNull final Class<? extends Activity> clz,
                                              final int requestCode,
                                              @AnimRes final int enterAnim,
                                              @AnimRes final int exitAnim) {
        startActivityForResult(activity, null, activity.getPackageName(), clz.getName(),
                requestCode, getOptionsBundle(activity, enterAnim, exitAnim));
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            activity.overridePendingTransition(enterAnim, exitAnim);
        }
    }

    /**
     * 启动 Activity 并带结果返回
     * @param extras      bundle 数据
     * @param activity    activity
     * @param clz         activity.class
     * @param requestCode 请求码
     */
    public static void startActivityForResult(@NonNull final Bundle extras,
                                              @NonNull final Activity activity,
                                              @NonNull final Class<? extends Activity> clz,
                                              final int requestCode) {
        startActivityForResult(activity, extras, activity.getPackageName(), clz.getName(),
                requestCode, null);
    }

    /**
     * 启动 Activity 并带结果返回 + 动画
     * @param extras      bundle 数据
     * @param activity    activity
     * @param clz         activity.class
     * @param requestCode 请求码
     * @param options     activity跳转方式
     */
    public static void startActivityForResult(@NonNull final Bundle extras,
                                              @NonNull final Activity activity,
                                              @NonNull final Class<? extends Activity> clz,
                                              final int requestCode,
                                              @NonNull final Bundle options) {
        startActivityForResult(activity, extras, activity.getPackageName(), clz.getName(),
                requestCode, options);
    }

    /**
     * 启动 Activity 并带结果返回 + 动画
     * @param extras         bundle 数据
     * @param activity       activity
     * @param clz            activity.class
     * @param requestCode    请求码
     * @param sharedElements 需要执行协调动画的view（可变参数）
     */
    public static void startActivityForResult(@NonNull final Bundle extras,
                                              @NonNull final Activity activity,
                                              @NonNull final Class<? extends Activity> clz,
                                              final int requestCode,
                                              final View... sharedElements) {
        startActivityForResult(activity, extras, activity.getPackageName(), clz.getName(),
                requestCode, getOptionsBundle(activity, sharedElements));
    }

    /**
     * 启动 Activity 并带结果返回 + 动画
     * @param extras      bundle 数据
     * @param activity    activity
     * @param clz         activity.class
     * @param requestCode 请求码
     * @param enterAnim   进入动画资源
     * @param exitAnim    退出动画资源
     */
    public static void startActivityForResult(@NonNull final Bundle extras,
                                              @NonNull final Activity activity,
                                              @NonNull final Class<? extends Activity> clz,
                                              final int requestCode,
                                              @AnimRes final int enterAnim,
                                              @AnimRes final int exitAnim) {
        startActivityForResult(activity, extras, activity.getPackageName(), clz.getName(),
                requestCode, getOptionsBundle(activity, enterAnim, exitAnim));
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            activity.overridePendingTransition(enterAnim, exitAnim);
        }
    }

    /**
     * 启动 Activity 并带结果返回
     * @param extras      bundle 数据
     * @param activity    activity
     * @param pkg         context.getPackageName()
     * @param cls         activity.class
     * @param requestCode 请求码
     */
    public static void startActivityForResult(@NonNull final Bundle extras,
                                              @NonNull final Activity activity,
                                              @NonNull final String pkg,
                                              @NonNull final String cls,
                                              final int requestCode) {
        startActivityForResult(activity, extras, pkg, cls, requestCode, null);
    }

    /**
     * 启动 Activity 并带结果返回 + 动画
     * @param extras      bundle 数据
     * @param activity    activity
     * @param pkg         context.getPackageName()
     * @param cls         activity.class
     * @param requestCode 请求码
     * @param options     activity跳转方式
     */
    public static void startActivityForResult(@NonNull final Bundle extras,
                                              @NonNull final Activity activity,
                                              @NonNull final String pkg,
                                              @NonNull final String cls,
                                              final int requestCode,
                                              final Bundle options) {
        startActivityForResult(activity, extras, pkg, cls, requestCode, options);
    }

    /**
     * 启动 Activity 并带结果返回 + 动画
     * @param extras         bundle 数据
     * @param activity       activity
     * @param pkg            context.getPackageName()
     * @param cls            activity.class
     * @param requestCode    请求码
     * @param sharedElements 需要执行协调动画的view（可变参数）
     */
    public static void startActivityForResult(@NonNull final Bundle extras,
                                              @NonNull final Activity activity,
                                              @NonNull final String pkg,
                                              @NonNull final String cls,
                                              final int requestCode,
                                              final View... sharedElements) {
        startActivityForResult(activity, extras, pkg, cls,
                requestCode, getOptionsBundle(activity, sharedElements));
    }

    /**
     * 启动 Activity 并带结果返回 + 动画
     * @param extras      bundle 数据
     * @param activity    activity
     * @param pkg         context.getPackageName()
     * @param cls         activity.class
     * @param requestCode 请求码
     * @param enterAnim   进入动画资源
     * @param exitAnim    退出动画资源
     */
    public static void startActivityForResult(@NonNull final Bundle extras,
                                              @NonNull final Activity activity,
                                              @NonNull final String pkg,
                                              @NonNull final String cls,
                                              final int requestCode,
                                              @AnimRes final int enterAnim,
                                              @AnimRes final int exitAnim) {
        startActivityForResult(activity, extras, pkg, cls,
                requestCode, getOptionsBundle(activity, enterAnim, exitAnim));
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            activity.overridePendingTransition(enterAnim, exitAnim);
        }
    }

    /**
     * 启动 Activity 并带结果返回
     * @param activity    activity
     * @param intent      intent
     * @param requestCode 请求码
     */
    public static void startActivityForResult(@NonNull final Activity activity,
                                              @NonNull final Intent intent,
                                              final int requestCode) {
        startActivityForResult(intent, activity, requestCode, null);
    }

    /**
     * 启动 Activity 并带结果返回  + 动画
     * @param activity    activity
     * @param intent      intent
     * @param requestCode 请求码
     * @param options     activity跳转方式
     */
    public static void startActivityForResult(@NonNull final Activity activity,
                                              @NonNull final Intent intent,
                                              final int requestCode,
                                              final Bundle options) {
        startActivityForResult(intent, activity, requestCode, options);
    }

    /**
     * 启动 Activity 并带结果返回  + 动画
     * @param activity       activity
     * @param intent         intent
     * @param requestCode    请求码
     * @param sharedElements 需要执行协调动画的view（可变参数）
     */
    public static void startActivityForResult(@NonNull final Activity activity,
                                              @NonNull final Intent intent,
                                              final int requestCode,
                                              final View... sharedElements) {
        startActivityForResult(intent, activity,
                requestCode, getOptionsBundle(activity, sharedElements));
    }

    /**
     * 启动 Activity 并带结果返回  + 动画
     * @param activity    activity
     * @param intent      intent
     * @param requestCode 请求码
     * @param enterAnim   进入动画资源
     * @param exitAnim    退出动画资源
     */
    public static void startActivityForResult(@NonNull final Activity activity,
                                              @NonNull final Intent intent,
                                              final int requestCode,
                                              @AnimRes final int enterAnim,
                                              @AnimRes final int exitAnim) {
        startActivityForResult(intent, activity,
                requestCode, getOptionsBundle(activity, enterAnim, exitAnim));
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            activity.overridePendingTransition(enterAnim, exitAnim);
        }
    }

    /**
     * 启动多个 Activity
     * @param intents intents
     */
    public static void startActivities(@NonNull final Intent[] intents) {
        startActivities(intents, Utils.getTopActivityOrApp(), null);
    }

    /**
     * 启动多个 Activity + 动画
     * @param intents intents
     * @param options activity跳转方式
     */
    public static void startActivities(@NonNull final Intent[] intents,
                                       final Bundle options) {
        startActivities(intents, Utils.getTopActivityOrApp(), options);
    }

    /**
     * 启动多个 Activity + 动画
     * @param intents   intents
     * @param enterAnim 进入动画资源
     * @param exitAnim  退出动画资源
     */
    public static void startActivities(@NonNull final Intent[] intents,
                                       @AnimRes final int enterAnim,
                                       @AnimRes final int exitAnim) {
        Context context = Utils.getTopActivityOrApp();
        startActivities(intents, context, getOptionsBundle(context, enterAnim, exitAnim));
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN && context instanceof Activity) {
            ((Activity) context).overridePendingTransition(enterAnim, exitAnim);
        }
    }

    /**
     * 启动多个 Activity
     * @param activity activity
     * @param intents  intents
     */
    public static void startActivities(@NonNull final Activity activity,
                                       @NonNull final Intent[] intents) {
        startActivities(intents, activity, null);
    }

    /**
     * 启动多个 Activity + 动画
     * @param activity activity
     * @param intents  intents
     * @param options  activity跳转方式
     */
    public static void startActivities(@NonNull final Activity activity,
                                       @NonNull final Intent[] intents,
                                       final Bundle options) {
        startActivities(intents, activity, options);
    }

    /**
     * 启动多个 Activity + 动画
     * @param activity  activity
     * @param intents   intents
     * @param enterAnim 进入动画资源
     * @param exitAnim  退出动画资源
     */
    public static void startActivities(@NonNull final Activity activity,
                                       @NonNull final Intent[] intents,
                                       @AnimRes final int enterAnim,
                                       @AnimRes final int exitAnim) {
        startActivities(intents, activity, getOptionsBundle(activity, enterAnim, exitAnim));
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            activity.overridePendingTransition(enterAnim, exitAnim);
        }
    }

    /**
     * 回到桌面
     */
    public static void startHomeActivity() {
        Intent homeIntent = new Intent(Intent.ACTION_MAIN);
        homeIntent.addCategory(Intent.CATEGORY_HOME);
        startActivity(homeIntent);
    }

    /**
     * 获取 Activity 栈链表
     */
    public static List<Activity> getActivityList() {
        return Utils.getActivityList();
    }

    /**
     * 获取启动项 Activity
     * @return 启动项 Activity 的String名字
     */
    public static String getLauncherActivity() {
        return getLauncherActivity(Utils.getApp().getPackageName());
    }

    /**
     * 获取启动项 Activity
     * @param pkg The name of the package.
     * @return 启动项 Activity 的名字
     * ResolveInfo:包含activity信息:name,activity、app包名,icon,应用名等
     *             ResolveInfo在清单中过滤到包含Intent.ACTION_MAIN,CATEGORY_LAUNCHER(可自定义action)
     */
    public static String getLauncherActivity(@NonNull final String pkg) {
        Intent intent = new Intent(Intent.ACTION_MAIN, null);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        PackageManager pm = Utils.getApp().getPackageManager();
        //利用Pkg Mgr解析Intent，得到所有能够处理Intent的Activity的ResolveInfo
        List<ResolveInfo> info = pm.queryIntentActivities(intent, 0);
        for (ResolveInfo aInfo : info) {
            if (aInfo.activityInfo.packageName.equals(pkg)) {
                return aInfo.activityInfo.name;
            }
        }
        return "no " + pkg;
    }

    /**
     * 获取栈顶 Activity
     */
    public static Activity getTopActivity() {
        return Utils.getActivityLifecycle().getTopActivity();
    }

    /**
     * 判断 Activity 是否存在栈中
     * @param activity activity
     */
    public static boolean isActivityExistsInStack(@NonNull final Activity activity) {
        List<Activity> activities = Utils.getActivityList();
        for (Activity aActivity : activities) {
            if (aActivity.equals(activity)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断 Activity 是否存在栈中
     * @param clz activity.class
     */
    public static boolean isActivityExistsInStack(@NonNull final Class<? extends Activity> clz) {
        List<Activity> activities = Utils.getActivityList();
        for (Activity aActivity : activities) {
            if (aActivity.getClass().equals(clz)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 结束 Activity
     * @param activity activity
     */
    public static void finishActivity(@NonNull final Activity activity) {
        finishActivity(activity, false);
    }

    /**
     * 结束 Activity
     * @param activity activity
     * @param isLoadAnim 是否加载动画
     */
    public static void finishActivity(@NonNull final Activity activity, final boolean isLoadAnim) {
        activity.finish();
        if (!isLoadAnim) {
            activity.overridePendingTransition(0, 0);
        }
    }

    /**
     * 结束 Activity + 动画
     * @param activity  activity
     * @param enterAnim 进入动画资源
     * @param exitAnim  退出动画资源
     */
    public static void finishActivity(@NonNull final Activity activity,
                                      @AnimRes final int enterAnim,
                                      @AnimRes final int exitAnim) {
        activity.finish();
        activity.overridePendingTransition(enterAnim, exitAnim);
    }

    /**
     * 结束 Activity,默认不加载动画
     * @param clz activity.class
     */
    public static void finishActivity(@NonNull final Class<? extends Activity> clz) {
        finishActivity(clz, false);
    }

    /**
     * 结束 Activity
     * @param clz        activity.class
     * @param isLoadAnim 是否加载动画
     */
    public static void finishActivity(@NonNull final Class<? extends Activity> clz,
                                      final boolean isLoadAnim) {
        List<Activity> activities = Utils.getActivityList();
        for (Activity activity : activities) {
            if (activity.getClass().equals(clz)) {
                activity.finish();
                if (!isLoadAnim) {
                    activity.overridePendingTransition(0, 0);
                }
            }
        }
    }

    /**
     * 结束 Activity
     * @param clz       activity.class
     * @param enterAnim 进入动画资源
     * @param exitAnim  退出动画资源
     */
    public static void finishActivity(@NonNull final Class<? extends Activity> clz,
                                      @AnimRes final int enterAnim,
                                      @AnimRes final int exitAnim) {
        List<Activity> activities = Utils.getActivityList();
        for (Activity activity : activities) {
            if (activity.getClass().equals(clz)) {
                activity.finish();
                activity.overridePendingTransition(enterAnim, exitAnim);
            }
        }
    }

    /**
     * 结束到指定 Activity
     * @param activity      activity
     * @param isIncludeSelf 是否包含自己
     */
    public static boolean finishToActivity(@NonNull final Activity activity,
                                           final boolean isIncludeSelf) {
        return finishToActivity(activity, isIncludeSelf, false);
    }

    /**
     * 结束到指定 Activity
     * @param activity      activity
     * @param isIncludeSelf 是否包含自己
     * @param isLoadAnim    是否加载动画
     */
    public static boolean finishToActivity(@NonNull final Activity activity,
                                           final boolean isIncludeSelf,
                                           final boolean isLoadAnim) {
        List<Activity> activities = Utils.getActivityList();
        for (int i = activities.size() - 1; i >= 0; --i) {
            Activity aActivity = activities.get(i);
            if (aActivity.equals(activity)) {
                if (isIncludeSelf) {
                    finishActivity(aActivity, isLoadAnim);
                }
                return true;
            }
            finishActivity(aActivity, isLoadAnim);
        }
        return false;
    }

    /**
     * 结束到指定 Activity
     * @param activity      activity
     * @param isIncludeSelf 是否包含自己
     * @param enterAnim 进入动画资源
     * @param exitAnim  退出动画资源
     */
    public static boolean finishToActivity(@NonNull final Activity activity,
                                           final boolean isIncludeSelf,
                                           @AnimRes final int enterAnim,
                                           @AnimRes final int exitAnim) {
        List<Activity> activities = Utils.getActivityList();
        for (int i = activities.size() - 1; i >= 0; --i) {
            Activity aActivity = activities.get(i);
            if (aActivity.equals(activity)) {
                if (isIncludeSelf) {
                    finishActivity(aActivity, enterAnim, exitAnim);
                }
                return true;
            }
            finishActivity(aActivity, enterAnim, exitAnim);
        }
        return false;
    }

    /**
     * 结束到指定 Activity
     * @param clz           activity.class
     * @param isIncludeSelf 是否包含自己
     */
    public static boolean finishToActivity(@NonNull final Class<? extends Activity> clz,
                                           final boolean isIncludeSelf) {
        return finishToActivity(clz, isIncludeSelf, false);
    }

    /**
     * 结束到指定 Activity
     * @param clz           activity.class
     * @param isIncludeSelf 是否包含自己
     * @param isLoadAnim    是否加载动画
     */
    public static boolean finishToActivity(@NonNull final Class<? extends Activity> clz,
                                           final boolean isIncludeSelf,
                                           final boolean isLoadAnim) {
        List<Activity> activities = Utils.getActivityList();
        for (int i = activities.size() - 1; i >= 0; --i) {
            Activity aActivity = activities.get(i);
            if (aActivity.getClass().equals(clz)) {
                if (isIncludeSelf) {
                    finishActivity(aActivity, isLoadAnim);
                }
                return true;
            }
            finishActivity(aActivity, isLoadAnim);
        }
        return false;
    }

    /**
     * 结束到指定 Activity
     * @param clz           activity.class
     * @param isIncludeSelf 是否包含自己
     * @param enterAnim     进入动画资源
     * @param exitAnim      退出动画资源
     */
    public static boolean finishToActivity(@NonNull final Class<? extends Activity> clz,
                                           final boolean isIncludeSelf,
                                           @AnimRes final int enterAnim,
                                           @AnimRes final int exitAnim) {
        List<Activity> activities = Utils.getActivityList();
        for (int i = activities.size() - 1; i >= 0; --i) {
            Activity aActivity = activities.get(i);
            if (aActivity.getClass().equals(clz)) {
                if (isIncludeSelf) {
                    finishActivity(aActivity, enterAnim, exitAnim);
                }
                return true;
            }
            finishActivity(aActivity, enterAnim, exitAnim);
        }
        return false;
    }

    /**
     * 结束所有其他类型的 Activity
     * @param clz activity.class
     */
    public static void finishOtherActivities(@NonNull final Class<? extends Activity> clz) {
        finishOtherActivities(clz, false);
    }


    /**
     * 结束所有其他类型的 Activity
     * @param clz        activity.class
     * @param isLoadAnim 是否加载动画
     */
    public static void finishOtherActivities(@NonNull final Class<? extends Activity> clz,
                                             final boolean isLoadAnim) {
        List<Activity> activities = Utils.getActivityList();
        for (int i = activities.size() - 1; i >= 0; i--) {
            Activity activity = activities.get(i);
            if (!activity.getClass().equals(clz)) {
                finishActivity(activity, isLoadAnim);
            }
        }
    }

    /**
     * 结束所有其他类型的 Activity
     * @param clz       activity.class
     * @param enterAnim 进入动画资源
     * @param exitAnim  退出动画资源
     */
    public static void finishOtherActivities(@NonNull final Class<? extends Activity> clz,
                                             @AnimRes final int enterAnim,
                                             @AnimRes final int exitAnim) {
        List<Activity> activities = Utils.getActivityList();
        for (int i = activities.size() - 1; i >= 0; i--) {
            Activity activity = activities.get(i);
            if (!activity.getClass().equals(clz)) {
                finishActivity(activity, enterAnim, exitAnim);
            }
        }
    }

    /**
     * 结束所有 Activity,默认不加载动画
     */
    public static void finishAllActivities() {
        finishAllActivities(false);
    }

    /**
     * 结束所有 Activity
     * @param isLoadAnim 是否加载动画
     */
    public static void finishAllActivities(final boolean isLoadAnim) {
        List<Activity> activityList = Utils.getActivityList();
        for (int i = activityList.size() - 1; i >= 0; --i) {// remove from top
            Activity activity = activityList.get(i);
            // sActivityList remove the index activity at onActivityDestroyed
            activity.finish();
            if (!isLoadAnim) {
                activity.overridePendingTransition(0, 0);
            }
        }
    }

    /**
     * 结束所有 Activity
     * @param enterAnim 进入动画资源
     * @param exitAnim  退出动画资源
     */
    public static void finishAllActivities(@AnimRes final int enterAnim,
                                           @AnimRes final int exitAnim) {
        List<Activity> activityList = Utils.getActivityList();
        for (int i = activityList.size() - 1; i >= 0; --i) {// remove from top
            Activity activity = activityList.get(i);
            // sActivityList remove the index activity at onActivityDestroyed
            activity.finish();
            activity.overridePendingTransition(enterAnim, exitAnim);
        }
    }

    /**
     * 结束除最新之外的所有 Activity,默认不加载动画
     */
    public static void finishAllActivitiesExceptNewest() {
        finishAllActivitiesExceptNewest(false);
    }

    /**
     * 结束除最新之外的所有 Activity,默认不加载动画
     * @param isLoadAnim 是否加载动画
     */
    public static void finishAllActivitiesExceptNewest(final boolean isLoadAnim) {
        List<Activity> activities = Utils.getActivityList();
        for (int i = activities.size() - 2; i >= 0; i--) {
            finishActivity(activities.get(i), isLoadAnim);
        }
    }

    /**
     * 结束除最新之外的所有 Activity,默认不加载动画
     * @param enterAnim 进入动画资源
     * @param exitAnim  退出动画资源
     */
    public static void finishAllActivitiesExceptNewest(@AnimRes final int enterAnim,
                                                       @AnimRes final int exitAnim) {
        List<Activity> activities = Utils.getActivityList();
        for (int i = activities.size() - 2; i >= 0; i--) {
            finishActivity(activities.get(i), enterAnim, exitAnim);
        }
    }

    /**
     * 返回Activity的icon
     * @param activity activity
     */
    public static Drawable getActivityIcon(@NonNull final Activity activity) {
        return getActivityIcon(activity.getComponentName());
    }

    /**
     * 返回Activity的icon
     * @param clz activity.class.
     */
    public static Drawable getActivityIcon(@NonNull final Class<? extends Activity> clz) {
        return getActivityIcon(new ComponentName(Utils.getApp(), clz));
    }

    /**
     * 返回Activity的icon
     * @param activityName activity的ComponentName
     * 原理：PackageManager.getActivityIcon
     */
    public static Drawable getActivityIcon(@NonNull final ComponentName activityName) {
        PackageManager pm = Utils.getApp().getPackageManager();
        try {
            return pm.getActivityIcon(activityName);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 返回Activity的logo
     * @param activity activity
     */
    public static Drawable getActivityLogo(@NonNull final Activity activity) {
        return getActivityLogo(activity.getComponentName());
    }

    /**
     * 返回Activity的logo
     * @param clz activity.class
     */
    public static Drawable getActivityLogo(@NonNull final Class<? extends Activity> clz) {
        return getActivityLogo(new ComponentName(Utils.getApp(), clz));
    }

    /**
     * 返回Activity的logo
     * @param activityName activityName
     */
    public static Drawable getActivityLogo(@NonNull final ComponentName activityName) {
        PackageManager pm = Utils.getApp().getPackageManager();
        try {
            return pm.getActivityLogo(activityName);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 启动activity 封装
     * @param context   上下文
     * @param extras    Bundle数据
     * @param pkg       包名
     * @param cls       类名
     * @param options   动画
     */
    private static void startActivity(final Context context,
                                      final Bundle extras,
                                      final String pkg,
                                      final String cls,
                                      final Bundle options) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        if (extras != null) intent.putExtras(extras);
        intent.setComponent(new ComponentName(pkg, cls));
        startActivity(intent, context, options);
    }

    /**
     * 启动activity 封装
     * @param intent    Intent
     * @param context   上下文
     * @param options   动画 api16-4.1 以上使用动画设置
     */
    private static void startActivity(final Intent intent,
                                      final Context context,
                                      final Bundle options) {
        if (!(context instanceof Activity)) {
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }
        if (options != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            context.startActivity(intent, options);
        } else {
            context.startActivity(intent);
        }
    }

    /**
     * 启动activityForResult 封装
     * @param activity    activity
     * @param extras      Bundle数据
     * @param pkg         pkg
     * @param cls         activity.cls
     * @param requestCode 请求码
     * @param options     动画 api16-4.1 以上使用动画设置
     */
    private static void startActivityForResult(final Activity activity,
                                               final Bundle extras,
                                               final String pkg,
                                               final String cls,
                                               final int requestCode,
                                               final Bundle options) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        if (extras != null) intent.putExtras(extras);
        intent.setComponent(new ComponentName(pkg, cls));
        startActivityForResult(intent, activity, requestCode, options);
    }

    /**
     * 启动activityForResult 封装
     * @param intent      intent
     * @param activity    activity
     * @param requestCode 请求码
     * @param options     动画 api16-4.1 以上使用动画设置
     */
    private static void startActivityForResult(final Intent intent,
                                               final Activity activity,
                                               final int requestCode,
                                               final Bundle options) {
        if (options != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {   //api16-4.1
            activity.startActivityForResult(intent, requestCode, options);
        } else {
            activity.startActivityForResult(intent, requestCode);
        }
    }

    //启动多个 Activity
    private static void startActivities(final Intent[] intents,
                                        final Context context,
                                        final Bundle options) {
        if (!(context instanceof Activity)) {
            for (Intent intent : intents) {
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            }
        }
        if (options != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {   //api16-4.1
            context.startActivities(intents, options);
        } else {
            context.startActivities(intents);
        }
    }

    //返回Bundle option(ActivityOptionsCompat.makeCustomAnimation)
    private static Bundle getOptionsBundle(final Context context,
                                           final int enterAnim,
                                           final int exitAnim) {
        return ActivityOptionsCompat.makeCustomAnimation(context, enterAnim, exitAnim).toBundle();
    }

    /**
     *  两个activity间多个view的协同场景动画（5.0以上才支持）
     *  原理：makeSceneTransitionAnimation(Activity activity, Pair... sharedElements)
     *        Pair imagePair = Pair.create(mImageView, getString(R.string.image));
     */
    private static Bundle getOptionsBundle(final Activity activity,
                                           final View[] sharedElements) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return null;
        if (sharedElements == null) return null;
        int len = sharedElements.length;
        if (len <= 0) return null;
        @SuppressWarnings("unchecked")
        Pair<View, String>[] pairs = new Pair[len];
        for (int i = 0; i < len; i++) {
            pairs[i] = Pair.create(sharedElements[i], sharedElements[i].getTransitionName());
        }
        return ActivityOptionsCompat.makeSceneTransitionAnimation(activity, pairs).toBundle();
    }
}
